#!/bin/bash

################################################################################
# MinIO 集群管理脚本
# 功能: 批量管理所有 MinIO 节点 (启动/停止/重启/状态/重载)
# 使用: ./minio-cluster-control.sh [start|stop|restart|status|reload]
################################################################################

set -e

# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
CYAN='\033[0;36m'
NC='\033[0m'

# MinIO 节点列表
NODES=("minio1" "minio2" "minio3" "minio4")

# 服务名称
SERVICE_NAME="minio"

# 显示使用帮助
show_usage() {
    echo -e "${BLUE}========================================${NC}"
    echo -e "${BLUE}MinIO 集群管理脚本${NC}"
    echo -e "${BLUE}========================================${NC}"
    echo ""
    echo -e "${YELLOW}使用方法:${NC}"
    echo -e "  $0 ${GREEN}[命令]${NC}"
    echo ""
    echo -e "${YELLOW}可用命令:${NC}"
    echo -e "  ${GREEN}start${NC}    - 启动所有 MinIO 节点"
    echo -e "  ${GREEN}stop${NC}     - 停止所有 MinIO 节点"
    echo -e "  ${GREEN}restart${NC}  - 重启所有 MinIO 节点"
    echo -e "  ${GREEN}reload${NC}   - 重新加载配置 (daemon-reload + restart)"
    echo -e "  ${GREEN}status${NC}   - 查看所有节点状态"
    echo -e "  ${GREEN}health${NC}   - 健康检查 (检查 MinIO API 响应)"
    echo ""
    echo -e "${YELLOW}示例:${NC}"
    echo -e "  $0 start      # 启动集群"
    echo -e "  $0 status     # 查看状态"
    echo -e "  $0 reload     # 重载配置并重启"
    echo ""
}

# 函数: 在单个节点执行命令
execute_on_node() {
    local node=$1
    local action=$2
    
    case ${action} in
        start)
            ssh ${node} "systemctl start ${SERVICE_NAME}"
            ;;
        stop)
            ssh ${node} "systemctl stop ${SERVICE_NAME}"
            ;;
        restart)
            ssh ${node} "systemctl restart ${SERVICE_NAME}"
            ;;
        reload)
            ssh ${node} "systemctl daemon-reload && systemctl restart ${SERVICE_NAME}"
            ;;
        status)
            ssh ${node} "systemctl status ${SERVICE_NAME} --no-pager -l"
            ;;
        is-active)
            ssh ${node} "systemctl is-active ${SERVICE_NAME}" 2>/dev/null || echo "inactive"
            ;;
        health)
            ssh ${node} "curl -s -o /dev/null -w '%{http_code}' http://localhost:9000/minio/health/live" 2>/dev/null || echo "000"
            ;;
        disk-status)
            # 检查 MinIO 数据目录挂载情况
            ssh ${node} "
                # 方法1: 尝试从配置文件读取 MINIO_VOLUMES
                config_file='/opt/linux_minio/minio.conf'
                if [ -f \"\$config_file\" ]; then
                    volumes=\$(grep MINIO_VOLUMES \"\$config_file\" 2>/dev/null | sed 's/.*MINIO_VOLUMES=//' | tr -d '\"' | tr '{},http://' '\n' | grep -E '^/' | sed 's|http.*:||' | sort -u)
                fi
                
                # 方法2: 如果没有找到，检测 /mnt/disk* 挂载点
                if [ -z \"\$volumes\" ]; then
                    volumes=\$(df -h | grep -E '/mnt/disk|/data' | awk '{print \$6}' | sort -u)
                fi
                
                # 方法3: 备用方案，显示所有大磁盘
                if [ -z \"\$volumes\" ]; then
                    df -h | awk '\$2 ~ /[0-9]+[TG]/ && \$2+0 > 10 && \$1 !~ /tmpfs|devtmpfs|overlay/ {print \$6,\$2,\$3,\$5}' | tr '\n' '|'
                else
                    # 输出找到的挂载点信息
                    for vol in \$volumes; do
                        df -h \$vol 2>/dev/null | tail -n1 | awk '{print \$6,\$2,\$3,\$5}'
                    done | tr '\n' '|'
                fi
            " 2>/dev/null || echo "N/A"
            ;;
    esac
}

# 函数: 批量执行命令
batch_execute() {
    local action=$1
    local action_name=$2
    
    echo -e "${BLUE}========================================${NC}"
    echo -e "${BLUE}${action_name}所有 MinIO 节点${NC}"
    echo -e "${BLUE}========================================${NC}"
    echo ""
    
    for node in "${NODES[@]}"; do
        echo -e "${YELLOW}[${node}]${NC} ${action_name}中..."
        
        if execute_on_node ${node} ${action}; then
            echo -e "${GREEN}[${node}]${NC} ✅ ${action_name}成功"
        else
            echo -e "${RED}[${node}]${NC} ❌ ${action_name}失败"
        fi
        echo ""
    done
}

# 函数: 显示集群状态
show_status() {
    echo -e "${BLUE}========================================${NC}"
    echo -e "${BLUE}MinIO 集群状态${NC}"
    echo -e "${BLUE}========================================${NC}"
    echo ""
    
    printf "${CYAN}%-10s %-15s %-10s %-15s${NC}\n" "节点" "服务状态" "健康检查" "运行时间"
    echo "------------------------------------------------------------"
    
    for node in "${NODES[@]}"; do
        # 获取服务状态
        status=$(execute_on_node ${node} is-active)
        
        # 获取健康检查
        health=$(execute_on_node ${node} health)
        
        # 获取运行时间
        uptime=$(ssh ${node} "systemctl show ${SERVICE_NAME} --property=ActiveEnterTimestamp --value 2>/dev/null" || echo "N/A")
        
        # 格式化输出
        if [ "${status}" == "active" ]; then
            status_display="${GREEN}运行中${NC}"
        else
            status_display="${RED}已停止${NC}"
        fi
        
        if [ "${health}" == "200" ]; then
            health_display="${GREEN}健康${NC}"
        else
            health_display="${RED}异常${NC}"
        fi
        
        # 简化运行时间显示
        if [ "${uptime}" != "N/A" ]; then
            uptime_short=$(echo ${uptime} | awk '{print $2, $3}')
        else
            uptime_short="N/A"
        fi
        
        printf "%-10s %-15s %-10s %-15s\n" "${node}" "$(echo -e ${status_display})" "$(echo -e ${health_display})" "${uptime_short}"
    done
    
    echo ""
}

# 函数: 详细状态检查
detailed_status() {
    echo -e "${BLUE}========================================${NC}"
    echo -e "${BLUE}MinIO 集群详细状态${NC}"
    echo -e "${BLUE}========================================${NC}"
    echo ""
    
    for node in "${NODES[@]}"; do
        echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
        echo -e "${YELLOW}节点: ${node}${NC}"
        echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
        execute_on_node ${node} status || echo -e "${RED}服务未运行${NC}"
        echo ""
    done
}

# 函数: 健康检查
health_check() {
    echo -e "${BLUE}========================================${NC}"
    echo -e "${BLUE}MinIO 集群健康检查${NC}"
    echo -e "${BLUE}========================================${NC}"
    echo ""
    
    HEALTHY_COUNT=0
    DISK_ISSUES=0
    
    for node in "${NODES[@]}"; do
        echo -e "${YELLOW}[${node}]${NC} 检查中..."
        
        # 检查服务状态 (防止 set -e 导致脚本退出)
        status=$(execute_on_node ${node} is-active || echo "inactive")
        
        # 检查 API 健康 (防止 set -e 导致脚本退出)
        health=$(execute_on_node ${node} health || echo "000")
        
        # 检查磁盘挂载状态
        disk_info=$(execute_on_node ${node} disk-status || echo "N/A")
        
        # 判断服务和 API 健康状态
        if [ "${status}" == "active" ] && [ "${health}" == "200" ]; then
            echo -e "${GREEN}[${node}]${NC} ✅ 健康 (服务运行中, API 响应正常)"
            ((HEALTHY_COUNT++)) || true
        elif [ "${status}" == "active" ]; then
            echo -e "${YELLOW}[${node}]${NC} ⚠️  服务运行中，但 API 无响应"
        else
            echo -e "${RED}[${node}]${NC} ❌ 服务未运行"
        fi
        
        # 显示磁盘挂载信息
        if [ "${disk_info}" != "N/A" ] && [ -n "${disk_info}" ]; then
            # 解析磁盘信息 (格式: 挂载点 总容量 已用 使用率|...)
            IFS='|' read -ra DISKS <<< "${disk_info}"
            
            if [ ${#DISKS[@]} -eq 0 ]; then
                echo -e "  ${RED}⚠️  磁盘: 未检测到 MinIO 数据盘挂载${NC}"
                ((DISK_ISSUES++)) || true
            else
                for disk in "${DISKS[@]}"; do
                    if [ -n "${disk}" ]; then
                        read -r mount total used percent <<< "${disk}"
                        
                        # 根据使用率显示不同颜色
                        usage_num=${percent%\%}
                        if [ ${usage_num} -ge 90 ]; then
                            disk_color="${RED}"
                        elif [ ${usage_num} -ge 75 ]; then
                            disk_color="${YELLOW}"
                        else
                            disk_color="${GREEN}"
                        fi
                        
                        echo -e "  ${CYAN}💾 磁盘: ${mount}${NC} - 总容量: ${total}, 已用: ${used} ${disk_color}(${percent})${NC}"
                    fi
                done
            fi
        else
            echo -e "  ${RED}⚠️  磁盘: 无法获取磁盘信息${NC}"
            ((DISK_ISSUES++)) || true
        fi
        
        echo ""
    done
    
    echo -e "${BLUE}========================================${NC}"
    echo -e "健康节点: ${GREEN}${HEALTHY_COUNT}${NC} / ${#NODES[@]}"
    
    if [ ${DISK_ISSUES} -gt 0 ]; then
        echo -e "磁盘问题: ${YELLOW}${DISK_ISSUES}${NC} 个节点存在磁盘挂载或空间问题"
    fi
    
    if [ ${HEALTHY_COUNT} -eq ${#NODES[@]} ] && [ ${DISK_ISSUES} -eq 0 ]; then
        echo -e "${GREEN}✅ 集群完全健康${NC}"
    elif [ ${HEALTHY_COUNT} -gt 0 ]; then
        echo -e "${YELLOW}⚠️  集群部分健康${NC}"
    else
        echo -e "${RED}❌ 集群不健康${NC}"
    fi
    echo ""
}

# 主程序
main() {
    # 检查参数
    if [ $# -eq 0 ]; then
        show_usage
        exit 1
    fi
    
    ACTION=$1
    
    case ${ACTION} in
        start)
            batch_execute "start" "启动"
            sleep 3
            show_status
            ;;
        stop)
            batch_execute "stop" "停止"
            sleep 2
            show_status
            ;;
        restart)
            batch_execute "restart" "重启"
            sleep 3
            show_status
            ;;
        reload)
            echo -e "${YELLOW}重新加载配置并重启服务...${NC}"
            echo ""
            batch_execute "reload" "重载配置"
            sleep 3
            show_status
            ;;
        status)
            show_status
            ;;
        status-detail)
            detailed_status
            ;;
        health)
            health_check
            ;;
        *)
            echo -e "${RED}错误: 未知命令 '${ACTION}'${NC}"
            echo ""
            show_usage
            exit 1
            ;;
    esac
}

# 执行主程序
main "$@"
